package mytest.bb;

import java.util.LinkedList;
import java.util.Random;

import sde.actor.Actor;
import sde.actor.Message;

public class BoundedBufferS extends Actor implements BufferIF{
	
	private final int size;
	
	private LinkedList<Integer> buffer;
	
	private final byte EMPTY = 0, PARTIAL = 1, FULL = 2;// STATI
	
	private Random random = new Random();

	public BoundedBufferS(int size) {
		this.size = size;
		buffer = new LinkedList<Integer>();
		become(EMPTY);
	}

	@Override
	public void handler(Message m) {
		switch(currentStatus()){
		case EMPTY:
			if (m instanceof Put) {
				put(m);
				if (buffer.size() == size) {
					become(FULL);
				}else{
					become(PARTIAL);
				}
			} else if (m instanceof Get) {
				defer(m);// non posso accettare una get
			}
			break;
		case PARTIAL:
			if (m instanceof Put) {
				put(m);
				if (buffer.size() == size) {
					become(FULL);
				}
			} else if (m instanceof Get) {
				get(m);
				if(buffer.isEmpty()){
					become(EMPTY);
				}
			}
			break;
		case FULL:
			if (m instanceof Put) {
				defer(m);
			} else if (m instanceof Get) {
				get(m);
				if (buffer.isEmpty()) {
					become(EMPTY);
				}else{
					become(PARTIAL);
				}
			}
			break;
		}
	}

	private void get(Message m) {
		Get gm = (Get)m;
		gm.reply(buffer.removeFirst().intValue(), now()+random.nextDouble()*100);
	}

	private void put(Message m) {
		Put pm = (Put) m;
		buffer.addLast(new Integer(pm.getVal()));
		pm.reply(now() + random.nextDouble() * 100);
	}
}
